package com.seu.clab.farm.controller;

import com.seu.clab.farm.common.CONST;
import com.seu.clab.farm.common.annotation.TokenRequired;
import com.seu.clab.farm.common.annotation.WebResponse;
import com.seu.clab.farm.model.dto.post.*;
import com.seu.clab.farm.model.dto.returnDTO.GetAccountListDTO;
import com.seu.clab.farm.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import com.google.gson.Gson;
import com.seu.clab.farm.exception.BizException;
import com.seu.clab.farm.model.dao.entity.Account;
import com.seu.clab.farm.model.dao.mapper.AccountMapper;
import com.seu.clab.farm.service.VerifyService;
import com.seu.clab.farm.util.ConstantUtil;
import com.seu.clab.farm.util.TokenUtil;
import lombok.Data;
import org.springframework.web.client.RestTemplate;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.util.Sqls;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.UUID;

@RestController
@CrossOrigin
@RequestMapping("/account")
@WebResponse
public class AccountController {
    @Autowired
    private HttpServletRequest request;

    @Autowired
    private AccountService accountService;

    @Autowired
    private AccountMapper accountMapper;

    @Autowired
    private VerifyService verifyService;

    @Autowired
    RestTemplate restTemplate;


    /**
     * 管理员获取手机验证码
     * @param phoneUsernameVerifier
     * @return
     * @throws Exception
     */
    @PostMapping("/admin")
    public Object getAdminCode(
            @RequestBody PhoneUsernameVerifier phoneUsernameVerifier
            )throws Exception{
        verifyService.postVerifyCode(request,phoneUsernameVerifier);
        return "验证码已发送！";
    }

    /**
     * 管理员登陆
     * @param phoneUsernameCodeVerifier
     * @return
     */
    @PostMapping("/admin/login")
    public Object adminLogin(
            @RequestBody PhoneUsernameCodeVerifier phoneUsernameCodeVerifier
    )throws NoSuchAlgorithmException {
        return verifyService.postLogin(request,phoneUsernameCodeVerifier);
    }

    /**
     * 登录
     * @param js_code
     * @return
     */
    @PostMapping("/login")
    public Object getLogin(
            @RequestParam String js_code
    ){
        String wxApiUrl = "https://api.weixin.qq.com/sns/jscode2session?" +
                "appid=" + CONST.appId +
                "&secret=" + CONST.appSecret +
                "&js_code=" + js_code +
                "&grant_type=authorization_code";
        String response = restTemplate.getForObject(wxApiUrl, String.class);
        Map res = new Gson().fromJson(response, Map.class);
        System.out.println(res);
        String openid = (String) res.get("openid");
        if(openid != null && !openid.equals("")){
            isRegister register = new isRegister();
            Account account = accountMapper.selectOneByExample(
                    Example.builder(Account.class).where(Sqls.custom().andEqualTo("openid",openid)).build()
            );

            //account为空时，则上面的if内部语句不会被执行，则name仍未初始值null
            //当account不为空时，name被重新赋值，从而进一步判断name有没有被注册过
            if(account != null){
                String name = account.getName();
                String accountId = account.getAccountId();
                if(name!=null&&!name.equals("")) {
                    register.setIsRegister(true);
                }else{
                    register.setIsRegister(false);
                }
                register.setToken(TokenUtil.createToken(accountId));
                return register;
            }else {
                Account newAccount = new Account();
                newAccount.setOpenid(openid);
                newAccount.setAccountId(UUID.randomUUID().toString());
                newAccount.setStartTime(new Date());
                accountMapper.insertSelective(newAccount);
                String token = TokenUtil.createToken(newAccount.getAccountId());
                register.setToken(token);
                register.setIsRegister(false);
                return register;
            }
        }else {
            throw new BizException(ConstantUtil.BizExceptionCause.NOT_OPENID);
        }

    }

    @Data
    class isRegister{
        Boolean isRegister;
        String token;
    }

    @PostMapping("/getToken")
    public Object getToken(){
        String accountId = "1e0c02fd-cbfa-402d-8399-50f58c15d732";
        String token = TokenUtil.createToken(accountId);
        System.out.println(token);
        return token;
    }

    /**
     * 注册
     * @param register
     * @return
     */
    @TokenRequired
    @PostMapping("/register")
    public Object test(
            @RequestBody Register register
    ){
        //获取accountId
        String accountId = (String) request.getAttribute(CONST.ACL_ACCOUNTID);
        System.out.println(accountId);
        accountService.registerUser(register,accountId);
        return CONST.SUCCESS_MESSAGE_DEFAULT;
    }

    @TokenRequired
    @PostMapping("/info")
    public Object changeAccountInfo(@Validated @RequestBody AccountDTO accountDTO) {
        accountDTO.setAccountId((String)request.getAttribute(CONST.ACL_ACCOUNTID));

        accountService.changeAccountInfo(accountDTO.toAccount());
        return "修改成功";
    }

    @TokenRequired
    @GetMapping("/phone")
    public Object getPhone()
    {
        return accountService.getPhone();
    }

    @TokenRequired
    @PostMapping("/phone")
    public Object changePhone(@Validated @RequestBody Map<String,Object> map){
        accountService.changePhone((String)map.get("phone"),(String)request.getAttribute(CONST.ACL_ACCOUNTID));
        return "修改成功";
    }

    @TokenRequired
    @GetMapping("/info")
    public Object getAccountInfo(){
        String accountId = (String) request.getAttribute(CONST.ACL_ACCOUNTID);
        return accountMapper.getAccountInfo(accountId);
    }

    @TokenRequired
    @GetMapping("/list")
    public Object getAccountList(@RequestParam Integer pageIndex){
        List<Map<String,Object>> list = accountMapper.getAccountList(pageIndex);
        Integer count = accountMapper.getAccountCount();
        GetAccountListDTO getAccountListDTO = new GetAccountListDTO(list,count);
        return  getAccountListDTO;
    }

    @TokenRequired
    @PostMapping("/modify")
    public Object modifyUser(@RequestBody AccountModifyDTO modifyDTO){
        Account account = accountMapper.selectByPrimaryKey(modifyDTO.getAccountId());
        account.setPhone(modifyDTO.getPhone());
        account.setEmail(modifyDTO.getEmail());
        account.setIdentify(modifyDTO.getIdentify());
        account.setName(modifyDTO.getName());
        accountMapper.updateByPrimaryKeySelective(account);
        return "success";
    }

    @TokenRequired
    @GetMapping("/search")
    public Object searchAccount(@RequestParam String name){
        return accountMapper.getSearchAccount(name);
    }
}
